local lobby = Server:addState("lobby")

function lobby:enteredState()
	print("server entered lobby state")
	--self.nature_base = loader.load("nature_base.tmx")
	--self.tech_base = loader.load("tech_base.tmx")
	self.jungle_start = 512
	self.jungle_end = 3104
	self.w = 256
	self.h = 256
	self.jungle_height = self.h-94
	self.jungle_width = self.w
	self.guest_update_timer = 0.2
	self.g_update = 0


end

function lobby:update(dt)
	self:receiveConnection(dt)
	local smc = love.thread.getChannel("jungle_map_server")
	local smcx = love.thread.getChannel("jungle_extra")
	local tsp = love.thread.getChannel("tech_spawn")
	local nsp = love.thread.getChannel("nature_spawn")

	if smc:peek() then
		self.map_string = smc:pop()
		--self.jungle = loader.load_from_string("jungle", self.map_string)
	end

	if smcx:peek() then
		self.extra_tiles = smcx:pop()
		--self:add_extra_tiles(self.extra_tiles)
	end

	if tsp:peek() then
		self.tech_spawn = tsp:pop()
	end

	if nsp:peek() then
		self.nature_spawn = nsp:pop()
	end
	self.g_update = self.g_update+ dt
	if self.g_update > self.guest_update_timer then
		self.g_update = 0
		self:update_guests(dt)	
	end
	
end

function lobby:update_guests(dt)
	local guest_pos = "{"
	if self.guests then

		for i = 1, #self.guests do
			if self.guests[i] then
				if self.guests[i].peer then				
					
					guest_pos = guest_pos .. self.guests[i]:get_position_string() 
					if #self.guests > 1 and i < #self.guests then
						guest_pos = guest_pos .. ", "
					end
					
				end
			end
		end
		guest_pos = guest_pos .. "}"


		for i = 1, #self.guests do
			if self.guests[i].peer then
				self.guests[i]:send_guest_locations(guest_pos)
			end
		end

	end
	
	


end

function lobby:receiveConnection(dt)
	local event = self.host:service(5)
	if event then
		if event.type == "receive" then
			print("Rcv msg: ", event.data, event.peer)
			if event.data == "hello world" then
				event.peer:send(event.data)			
			end

			local cmds = self:parse(event.data)
			if cmds then
				for i = 1, #cmds do
					if cmds[i].cmd == "[email]" then
						local guest = self:find_guest_file(cmds[i].data)
						if not guest then
							print("guest file not found, making new guest")
							local guest = self:add_new_guest(tostring(event.peer))
							guest:set_email(cmds[i].data)
						else
							local og = Guest:new(tostring(event.peer))
							og:set_email(guest.email)
							og:set_pass(guest.pass)
							print("guest file found, adding to connected guests", guest.email, guest.pass)
							og.stats = guest.stats
							og.name = guest.name
							og.gender = guest.gender
							self:add_guest(og)
						end
						event.peer:send("send_pwd")
					elseif cmds[i].cmd == "[pass]" then
						print("executing pass command for " .. tostring(event.peer))
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then 
							print(guest:get_email())
							local gfile = self:find_guest_file(guest:get_email())
							if gfile then
								if gfile.pass == cmds[i].data then
									print("user authorized")
									-- remove true when live or every user is always new
									--guest:connected(event.peer, true)
									guest:connected(event.peer, false, self.map_string, self.extra_tiles)
								else
									print("user not authorized")
									event.peer:send("login_reset")
									self:disconnect_guest(guest_id)									
								end
							else
								guest:set_pass(cmds[i].data)
								guest:save()
								print("new user made email " .. guest.email .. " pass " .. guest.pass)
								guest:connected(event.peer, true, self.map_string, self.extra_tiles)
							end

						end
					elseif cmds[i].cmd == "[stat]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							local stats = self:parse_stat(cmds[i].data)
							if stats then
								for j = 1, #stats do
									local stat_name = stats[j].cmd:sub(2, -2)
									print("stat received ..", stat_name, stats[j].data)
									guest:add_unsafe_stat(stat_name, stats[j].data)

								end
							end
						end
					elseif cmds[i].cmd == "[stat_stream_finished]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:validate_unsafe_stats()
						end

					elseif cmds[i].cmd == "[train]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:add_unsafe_skill(cmds[i].data, "train")
						end
					elseif cmds[i].cmd == "[spec]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:add_unsafe_skill(cmds[i].data, "spec")
						end
					elseif cmds[i].cmd == "[skill_stream_finished]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							if guest:validate_unsafe_skills() then
								event.peer:send("[enter_game]")
							end

						end
					elseif cmds[i].cmd == "[team]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:set_team(cmds[i].data)
							if cmds[i].data == "Nature" then
								guest:set_position(self.nature_spawn.x, self.nature_spawn.y)				
								
							elseif cmds[i].data == "Tech" then
								guest:set_position(self.tech_spawn.x, self.tech_spawn.y)
							end

						end
					elseif cmds[i].cmd == "[say]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							self:guest_say(guest, cmds[i].data)
						end
					elseif cmds[i].cmd == "[move_up]" then
						
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:move(0, -1, dt, tostring(event.peer))
						end
					elseif cmds[i].cmd == "[move_down]" then
					
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:move(0, 1, dt, tostring(event.peer))
						end
					elseif cmds[i].cmd == "[move_right]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:move(1, 0, dt, tostring(event.peer))
						end
					elseif cmds[i].cmd == "[move_left]" then
						local guest, guest_id = self:find_guest(tostring(event.peer))
						if guest then
							guest:move(-1, 0, dt, tostring(event.peer))
						end
					end
				end
			end
		end

		if event.type == "disconnect" then
			local guest, id = self:find_guest(tostring(event.peer))
			if id then
				self:disconnect_guest(id)
			end
		end
	end
end

function lobby:add_extra_tiles(extra_tiles)
	local et1, num = extra_tiles:gsub("(%a)", "%[\"%1\"%]")
	--print("extra tiles .. " .. et1)



	local s = "return " .. et1

	local chunk = loadstring(s)

	local et = chunk()	
	
	for i = 1, #et do
		local layer
		if et[i].v <= 12 then
			layer = "ground"
		else
			layer = "ground_decor"
		end
		self.jungle.layers[layer]:set(et[i].x, et[i].y, self.jungle.tiles[et[i].v])
	end
	
	
end


function lobby:exitedState()
	print("server exited lobby")
end